<template>
  <!-- 登录页主容器：包含整个登录界面，设置了渐变背景 -->
  <div class="login-container">
    <!-- 登录框：包含登录表单和装饰元素 -->
    <div class="login-box">
      <!-- Logo区域：使用六边形容器实现特殊形状的Logo -->
      <div class="logo-container">
        <div class="hexagon-logo">
          <img src="@/assets/logo.png" alt="智慧社区" class="logo-img">
        </div>
      </div>
      
      <!-- 系统标题区域 -->
      <h2 class="system-title">智慧社区SaaS服务平台</h2>
      <!-- 系统副标题/英文描述 -->
      <div class="system-subtitle">SaaS service platform of smart community</div>
      
      <!-- 登录表单容器：包含两种登录方式的选项卡 -->
      <div class="login-form-container">
        <!-- 登录方式选项卡：账号密码/人脸识别 -->
        <el-tabs v-model="activeTab" class="login-tabs" :stretch="true">
          <!-- 账号密码登录选项卡 -->
          <el-tab-pane label="账号密码登录" name="account">
            <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
              <!-- 账号输入框 -->
              <el-form-item prop="account">
                <el-input 
                  v-model="loginForm.account" 
                  placeholder="请输入账号" 
                  prefix-icon="el-icon-user">
                </el-input>
              </el-form-item>
              
              <!-- 密码输入框 -->
              <el-form-item prop="password">
                <el-input 
                  v-model="loginForm.password" 
                  type="password" 
                  placeholder="请输入密码" 
                  prefix-icon="el-icon-lock">
                </el-input>
              </el-form-item>
              
              <!-- 登录按钮 -->
              <el-form-item>
                <el-button type="primary" :loading="loading" @click="handleLogin('loginForm')" class="login-button">登 录</el-button>
              </el-form-item>
            </el-form>
          </el-tab-pane>
          
          <!-- 人脸识别登录选项卡 -->
          <el-tab-pane label="人脸识别登录" name="face">
            <div class="face-login">
              <!-- 视频捕捉区域：显示摄像头画面和人脸识别框 -->
              <div class="video-container">
                <video ref="video" autoplay></video>
                <canvas ref="canvas" style="display: none;"></canvas>
                <!-- 人脸捕获框：当摄像头开启时显示 -->
                <div class="capture-box" v-if="isStreaming"></div>
                <!-- 未开启摄像头时的提示 -->
                <div class="no-camera" v-if="!isStreaming">
                  <i class="el-icon-video-camera"></i>
                  <span>正在开启摄像头...</span>
                </div>
              </div>
              
              <!-- 人脸识别状态提示 -->
              <div class="face-status" v-if="faceRecognizing">
                <i class="el-icon-loading"></i> 正在识别中...
              </div>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>
      
      <!-- 页脚版权信息 -->
      <div class="footer-text">
        Copyright © 2023 智慧社区SaaS服务平台 All Rights Reserved
      </div>
    </div>
  </div>
</template>

<script>
export default {
  // 组件名称
  name: 'Login',
  data() {
    return {
      activeTab: 'account', // 默认选中的登录方式：账号密码登录
      // 表单数据：存储账号密码
      loginForm: {
        account: '',  // 账号
        password: ''  // 密码
      },
      // 表单验证规则
      loginRules: {
        account: [
          { required: true, message: '请输入账号', trigger: 'blur' },
          { min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          { min: 6, max: 20, message: '长度在 6 到 20 个字符', trigger: 'blur' }
        ]
      },
      loading: false,         // 登录按钮加载状态
      stream: null,           // 摄像头流对象
      isStreaming: false,     // 摄像头是否开启
      faceRecognizing: false, // 人脸识别中状态
      // 定时识别相关配置
      recognizeTimer: null,       // 定时器对象
      recognizeInterval: 1500     // 识别间隔：1.5秒
    }
  },
  watch: {
    /**
     * 监听登录方式切换
     * 自动管理摄像头开关
     */
    activeTab(newVal) {
      // 当切换到人脸识别时，自动开启摄像头
      if (newVal === 'face' && !this.isStreaming) {
        this.startCamera();
      }
      // 当切换到账号密码登录时，关闭摄像头
      if (newVal === 'account' && this.isStreaming) {
        this.stopCamera();
      }
    }
  },
  // 组件销毁前清理资源
  beforeDestroy() {
    this.stopCamera();
    this.clearRecognizeTimer();
  },
  methods: {
    /**
     * 账号密码登录处理
     * 验证表单并提交登录请求
     * @param {String} formName - 表单引用名称
     */
    handleLogin(formName) {
      this.$refs[formName].validate(async (valid) => {
        if (valid) {
          // 表单验证通过，开始登录流程
          this.loading = true;
          try {
            // 使用GET请求，直接传递参数
            const account = this.loginForm.account;
            const password = this.loginForm.password;
            
            // 发送登录请求
            const response = await this.$axios.get(`/api/uums-server/user/loginByAccount?account=${account}&password=${password}`);
            
            if (response.data.code === 200) {
              // 登录成功：保存token和账号，显示成功提示
              this.$message.success('登录成功');
              localStorage.setItem('token', response.data.data);
              localStorage.setItem('account', this.loginForm.account);

              
              // 跳转到首页或工作台
              this.$router.push({path:'/'}).catch(err => {
                if (err.name === 'NavigationDuplicated') {
                  // 忽略重复导航错误
                  console.log('导航已在当前位置，忽略重复导航');
                } else {
                  // 处理其他导航错误
                  console.error('导航错误:', err);
                }
              });
            }else if(response.data.code === 602){
              // 处理特定错误码：账号不存在或密码错误
              this.$message.error(response.data.msg);
            }else if(response.data.code === 607){
              // 处理特定错误码：账号未激活
              this.$message.error(response.data.msg);
            }
            else if(response.data.code === 606){
              // 处理特定错误码：账号已停用
              this.$message.error(response.data.msg);
            }else if(response.data.code === 605){
              // 处理特定错误码：权限不足
              this.$message.error(response.data.msg);
            }
            else {
              // 其他未知错误
              this.$message.error('登录失败');
            }
          } catch (error) {
            // 处理请求异常
            console.error('登录错误:', error);
            this.$message.error('登录失败，请稍后再试');
          } finally {
            // 无论成功失败，都结束加载状态
            this.loading = false;
          }
        } else {
          // 表单验证不通过，显示提示
          this.$message.warning('请正确填写登录信息');
          return false;
        }
      });
    },
    
    /**
     * 开启摄像头
     * 请求摄像头权限并启动视频流
     */
    async startCamera() {
      try {
        // 请求摄像头访问权限
        this.stream = await navigator.mediaDevices.getUserMedia({
          video: true,
          audio: false
        });
        
        // 设置视频源并更新状态
        this.$refs.video.srcObject = this.stream;
        this.isStreaming = true;
        
        // 开启自动识别定时器
        this.startRecognizeTimer();
        
      } catch (error) {
        // 摄像头访问失败处理
        this.$message.error('无法访问摄像头，请确保已授予权限');
        console.error('摄像头访问错误:', error);
      }
    },
    
    /**
     * 停止摄像头
     * 关闭视频流并清理资源
     */
    stopCamera() {
      if (this.stream) {
        // 停止所有视频轨道
        this.stream.getTracks().forEach(track => track.stop());
        this.isStreaming = false;
      }
      // 清除定时识别
      this.clearRecognizeTimer();
    },
    
    /**
     * 设置定时识别
     * 创建定时器定期执行人脸识别
     */
    startRecognizeTimer() {
      this.clearRecognizeTimer(); // 先清除之前的定时器
      this.recognizeTimer = setInterval(() => {
        // 仅在摄像头开启且未在识别过程中时执行识别
        if (this.isStreaming && !this.faceRecognizing) {
          this.recognizeFace();
        }
      }, this.recognizeInterval);
    },
    
    /**
     * 清除定时识别
     * 停止定时器，避免资源浪费
     */
    clearRecognizeTimer() {
      if (this.recognizeTimer) {
        clearInterval(this.recognizeTimer);
        this.recognizeTimer = null;
      }
    },
    
    /**
     * 人脸识别登录
     * 捕获摄像头图像并发送到后端进行识别
     */
    async recognizeFace() {
      if (!this.isStreaming || this.faceRecognizing) return;
      
      // 设置识别中状态
      this.faceRecognizing = true;
      
      try {
        // 获取视频和Canvas元素
        const video = this.$refs.video;
        const canvas = this.$refs.canvas;
        const context = canvas.getContext('2d');
        
        // 设置canvas尺寸与视频一致
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        
        // 绘制视频帧到canvas
        context.drawImage(video, 0, 0, canvas.width, canvas.height);
        
        // 获取canvas的图像数据并转为Blob
        canvas.toBlob(async (blob) => {
          try {
            const reader = new FileReader();
            
            // 使用Promise包装FileReader操作
            const base64Promise = new Promise((resolve) => {
              reader.onload = () => {
                const fullBase64 = reader.result;
                // 去掉前缀，获取纯base64数据
                resolve(fullBase64.split(',')[1]);
              };
            });
            
            // 读取Blob为DataURL格式
            reader.readAsDataURL(blob);
            
            // 等待FileReader完成读取
            const finalBase64 = await base64Promise;
            
            // 发送人脸识别请求：使用POST方法发送base64数据
            const response = await this.$axios.post('/api/uums-server/user/loginByFace', finalBase64, {
              headers: {
                'Content-Type': 'text/plain' // 确保不会自动进行URL编码
              }
            });
            
            if (response.data.code === 200) {
              // 人脸识别登录成功
              this.$message.success('人脸识别登录成功');
              localStorage.setItem('token', response.data.data);
              localStorage.setItem('account', '用户_' + new Date().getTime().toString().slice(-4));
              // 跳转到首页
              this.$router.push({path:'/'}).catch(err => {
                if (err.name === 'NavigationDuplicated') {
                  // 忽略重复导航错误
                  console.log('导航已在当前位置，忽略重复导航');
                } else {
                  // 处理其他导航错误
                  console.error('导航错误:', err);
                }
              });
            }else if(response.data.code === 603){
              // 处理特定错误码：人脸未识别到
              this.$message.error(response.data.msg);
            }else if(response.data.code === 601){
              // 处理特定错误码：未检测到人脸
              this.$message.error(response.data.msg);
            }else if(response.data.code === 602){
              // 处理特定错误码：人脸不匹配
              this.$message.error(response.data.msg);
            } 
            else if(response.data.code === 608){
              // 处理特定错误码：账号已停用
              this.$message.error(response.data.msg);
            } else if(response.data.code === 609){
              // 处理特定错误码：未找到相关账号
              this.$message.error(response.data.msg);
            }else if(response.data.code === 610){
              // 处理特定错误码：账号未激活
              this.$message.error(response.data.msg);
            }else{
              // 其他未知错误
              this.$message.error('人脸识别登录失败');
            }
          } catch (error) {
            // 处理请求异常
            console.error('人脸识别登录出错:', error);
            this.$message.error('人脸识别登录时发生错误');
          } finally {
            // 完成识别，重置状态
            this.faceRecognizing = false;
          }
        }, 'image/jpeg', 0.95); // 指定JPEG格式，95%质量
      } catch (error) {
        // 处理Canvas操作异常
        console.error('人脸识别错误:', error);
        this.$message.error('无法处理摄像头图像');
        this.faceRecognizing = false;
      }
    }
  },
  // 组件挂载完成后执行
  mounted() {
    // 如果初始标签是人脸识别，自动开启摄像头
    if (this.activeTab === 'face') {
      this.startCamera();
    }
  }
}
</script>

<style scoped>
/* 登录容器：设置全屏渐变背景 */
.login-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-color: #0066ff;
  background-image: radial-gradient(circle at bottom right, #0077ff, #0055ff);
  position: relative;
  overflow: hidden;
}

/* 背景装饰：添加六边形图案作为背景装饰 */
.login-container::before {
  content: '';
  position: absolute;
  width: 100%;
  height: 100%;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M50,30 L70,40 L70,60 L50,70 L30,60 L30,40 Z" fill="none" stroke="rgba(255,255,255,0.1)" stroke-width="1"/></svg>');
  background-size: 300px 300px;
  opacity: 0.3;
}

/* 登录框：白色卡片样式，带阴影和圆角 */
.login-box {
  width: 400px;
  padding: 40px;
  background: #fff;
  border-radius: 4px;
  box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.1);
  text-align: center;
  position: relative;
  z-index: 10;
}

/* Logo容器：居中显示Logo */
.logo-container {
  display: flex;
  justify-content: center;
  margin-bottom: 20px;
}

/* 六边形Logo：创建六边形形状的Logo容器 */
.hexagon-logo {
  width: 70px;
  height: 70px;
  background-color: #0066ff;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
}

/* Logo图片：控制Logo大小和适应方式 */
.logo-img {
  width: 40px;
  height: 40px;
  object-fit: contain;
}

/* 系统标题：设置标题样式 */
.system-title {
  margin: 0;
  font-size: 20px;
  font-weight: 500;
  color: #333;
}

/* 系统副标题：设置副标题样式 */
.system-subtitle {
  font-size: 12px;
  color: #909399;
  margin-bottom: 30px;
}

/* 登录表单容器：设置垂直间距 */
.login-form-container {
  margin: 20px 0;
}

/* 选项卡样式：自定义Element UI选项卡的样式 */
.login-tabs >>> .el-tabs__active-bar {
  background-color: #0066ff;
  height: 2px;
}

.login-tabs >>> .el-tabs__item {
  font-size: 15px;
  color: #606266;
  transition: all 0.3s;
}

.login-tabs >>> .el-tabs__item.is-active {
  color: #0066ff;
  font-weight: 500;
}

.login-tabs >>> .el-tabs__nav-wrap::after {
  height: 1px;
  background-color: #e4e7ed;
}

/* 登录表单：设置表单间距 */
.login-form {
  margin-top: 20px;
}

/* 表单项样式：设置底部间距 */
.login-form >>> .el-form-item {
  margin-bottom: 20px;
}

/* 输入框样式：自定义Element UI输入框的外观 */
.login-form >>> .el-input__inner {
  height: 40px;
  line-height: 40px;
  border-radius: 4px;
  border: 1px solid #dcdfe6;
  color: #606266;
  font-size: 14px;
}

.login-form >>> .el-input__inner:focus {
  border-color: #0066ff;
}

.login-form >>> .el-input__prefix {
  color: #c0c4cc;
}

/* 登录按钮样式：设置按钮的外观和悬停效果 */
.login-button {
  width: 100%;
  height: 40px;
  font-size: 16px;
  background-color: #0066ff;
  border-color: #0066ff;
  border-radius: 4px;
  transition: all 0.3s;
}

.login-button:hover,
.login-button:focus {
  background-color: #0077ff;
  border-color: #0077ff;
}

/* 人脸识别登录区域样式 */
.face-login {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 15px 0;
}

/* 视频容器：设置摄像头画面的显示框 */
.video-container {
  position: relative;
  width: 280px;
  height: 210px;
  margin-bottom: 20px;
  border-radius: 4px;
  overflow: hidden;
  background-color: #f5f7fa;
  border: 1px solid #e6e6e6;
}

/* 视频元素：适应容器大小 */
.video-container video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* 无摄像头状态显示：摄像头未开启时的提示 */
.no-camera {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: #909399;
}

/* 无摄像头图标样式 */
.no-camera i {
  font-size: 40px;
  margin-bottom: 10px;
}

/* 人脸捕获框：在视频上显示的边框，用于引导用户 */
.capture-box {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: 2px dashed #0066ff;
  box-sizing: border-box;
}

/* 人脸识别状态提示：显示识别中状态 */
.face-status {
  color: #0066ff;
  font-size: 14px;
  display: flex;
  align-items: center;
}

/* 加载图标样式 */
.face-status i {
  margin-right: 5px;
}

/* 页脚文字：版权信息样式 */
.footer-text {
  margin-top: 20px;
  font-size: 12px;
  color: #909399;
}
</style>